from snbpy.common.domain.snb_config import SnbConfig
from snbpy.snb_api_client import SnbHttpClient
from snbpy.common.constant.snb_constant import SecurityType,OrderSide,Currency,OrderType,TimeInForce
from utility import code_futu_to_snowball
import json
import pandas as pd
import time
from threading import RLock


class snowball():
    def __init__(self):
        self.config = SnbConfig()
        # self.config.account = "DU1234567"
        # self.config.key = "123456"
        # self.config.snb_server = 'sandbox.snbsecurities.com'
        self.config.account = "U9351168"
        self.config.key = "123456789"
        self.config.snb_server = 'openapi.snbsecurities.com'
        self.config.sign_type = 'None'
        self.config.snb_port = '443'
        self.config.timeout = 1000
        self.config.schema = 'https'
        self.last_ts = 0
        self.sq = 0
        self.lock = RLock()
        self.client = SnbHttpClient(self.config)
        self.client.login()

    def gen_order_id(self):
        with self.lock:
            t = int(time.time())
            if self.last_ts == t:
                if self.sq == 999:
                    raise Exception("too many request in one second")
                else:
                    self.sq += 1
            else:
                self.last_ts = t
                self.sq = 0
            return "{}{:03}".format(self.last_ts, self.sq)

    def buy(self,code:str,vol:int):
        order_id = self.gen_order_id()
        order_buy = self.client.place_order(order_id, 
                                SecurityType.STK, 
                                code, 
                                "", OrderSide.BUY, Currency.HKD, 
                                vol,
                                0, OrderType.MARKET, 
                                TimeInForce.DAY, 
                                True)
        order_buy
        print(order_buy.result_str)
        if order_buy.succeed():
            print("buy succeed")
            cancel_result = snb.client.cancel_order(snb.gen_order_id(), order_id)
            print(cancel_result.result_str)
        else:
            print("buy failed")

        
    def sell(self,code:str,vol:int):
        order_id = self.gen_order_id()
        order_sell = self.client.place_order(order_id, 
                                SecurityType.STK, 
                                code, 
                                "", OrderSide.SELL, Currency.HKD, 
                                vol, 
                                0, OrderType.MARKET, 
                                TimeInForce.DAY, 
                                True)
        order_sell
        print(order_sell.result_str)
        if order_sell.succeed():
            print("sell succeed")
            cancel_result = snb.client.cancel_order(snb.gen_order_id(), order_id)
            print(cancel_result.result_str)
        else:
            print("sell failed")

    def balance(self):
        return pd.DataFrame(json.loads(self.client.get_balance().result_str)['result_data'])

    def net_value(self):
        return pd.DataFrame(json.loads(self.client.get_balance().result_str)['result_data'])['net_liquidation_value'][0]
    
    def cash(self):
        return pd.DataFrame(json.loads(self.client.get_balance().result_str)['result_data'])['cash'][0]
    
    def available_funds(self):
        return pd.DataFrame(json.loads(self.client.get_balance().result_str)['result_data'])['current_available_funds'][0]

    #杠杆率
    def leverage(self):
        return pd.DataFrame(json.loads(self.client.get_balance().result_str)['result_data'])['leverage'][0]

    def holdings(self):
        position_list = pd.DataFrame(json.loads(self.client.get_position_list().result_str)['result_data'])
        if not position_list.empty:
            return position_list
        return 0

# if __name__ == '__main__':
snb = snowball()
# print(snb.cash())



